/**
 * describe:
 *
 * @author chaP
 * @date 2019/04/09
 */
package CodingTest.AC20190409;

/**
 * leetcode - 289
 * 根据百度百科，生命游戏，简称为生命，是英国数学家约翰·何顿·康威在1970年发明的细胞自动机。

 给定一个包含 m × n 个格子的面板，每一个格子都可以看成是一个细胞。每个细胞具有一个初始状态 live（1）即为活细胞， 或 dead（0）即为死细胞。每个细胞与其八个相邻位置（水平，垂直，对角线）的细胞都遵循以下四条生存定律：

 如果活细胞周围八个位置的活细胞数少于两个，则该位置活细胞死亡；
 如果活细胞周围八个位置有两个或三个活细胞，则该位置活细胞仍然存活；
 如果活细胞周围八个位置有超过三个活细胞，则该位置活细胞死亡；
 如果死细胞周围正好有三个活细胞，则该位置死细胞复活；
 根据当前状态，写一个函数来计算面板上细胞的下一个（一次更新后的）状态。下一个状态是通过将上述规则同时应用于当前状态下的每个细胞所形成的，其中细胞的出生和死亡是同时发生的。

 示例:

 输入:
 [
 [0,1,0],
 [0,0,1],
 [1,1,1],
 [0,0,0]
 ]
 输出:
 [
 [0,0,0],
 [1,0,1],
 [0,1,1],
 [0,1,0]
 ]
 */
public class gameOfLife {
    public void gameOfLife(int [][] board){
//        int m = board.length;
//        int n = board[0].length;
//        for(int i = 0;i<m;i++){//i:行
//            for(int j = 0;j<n;j++){//j:列
//                int count =0;
//                //检查左上角：
//                if(i-1>=0&&j-1>=0&&(board[i-1][j-1] == 1||board[i-1][j-1] == 2)){
//                    count ++;
//                }
//                //检查左上方：
//                if(i-1>=0&&(board[i-1][j] == 1||board[i-1][j] == 2)){
//                    count ++;
//                }
//                //检查右上角
//                if(i-1>=0&&j+1<n&&(board[i-1][j+1] == 1||board[i-1][j+1] == 2)){
//                    count ++;
//                }
//                //检查左边
//                if(j-1>=0&&(board[i][j-1] == 1||board[i][j-1] == 2)){
//                    count ++;
//                }
//                //检查右边
//                if(j+1< n &&(board[i][j+1] == 1||board[i][j+1] == 2)){
//                    count ++;
//                }
//                //检查左下角
//                if(i+1<m&&j-1>=0&&(board[i+1][j-1] == 1||board[i+1][j-1] == 2)){
//                    count ++;
//                }
//                //检查下方
//                if(i+1<m&&(board[i+1][j] == 1||board[i+1][j] == 2)){
//                    count ++;
//                }
//                //检查右下角
//
//                if(i+1<m&&j+1<n&&(board[i+1][j] == 1||board[i+1][j] == 2)){
//                    count ++;
//                }
//                if(count == 3 &&board[i][j] == 0 ){
//                    board[i][j] =3;
//                }if((count == 3||count == 2) && board[i][j] == 1){
//                    board[i][j] = 1;
//                }
//                if((count <2||count >3)&&board[i][j] == 1){
//                    board[i][j] = 2;
//                }
//            }
//
//        }
//        for(int i = 0;i<m;i++){//i:行
//            for(int j = 0;j<n;j++){//j:列
//                board[i][j] = board[i][j]%2;
//                 }}
        int m = board.length, n = board[0].length;
        for(int i = 0; i < m; ++i){
            for(int j = 0; j < n; ++j){
                int lives = 0;
                if(i > 0){//判断上边
                    lives += board[i-1][j] == 1 || board[i-1][j] == 2 ? 1:0;
                }
                if(i > 0 && j < n - 1){//判断右上角
                    lives += board[i-1][j+1] == 1 || board[i-1][j+1] == 2 ? 1:0;
                }
                if(j < n - 1){//判断右边
                    lives += board[i][j+1] == 1 || board[i][j+1] == 2 ? 1:0;
                }
                if(i < m - 1 && j < n - 1){//判断右下角
                    lives += board[i+1][j+1] == 1 || board[i+1][j+1] == 2 ? 1:0;
                }
                if(i < m - 1){//判断下边
                    lives += board[i+1][j] == 1 || board[i+1][j] == 2 ? 1:0;
                }
                if(i < m - 1 && j > 0){//判断左下角
                    lives += board[i+1][j-1] == 1 || board[i+1][j-1] == 2 ? 1:0;
                }
                if(j > 0){//判断左边
                    lives += board[i][j-1] == 1 || board[i][j-1] == 2 ? 1:0;
                }
                if(i > 0 && j > 0){//判断左上角
                    lives += board[i-1][j-1] == 1 || board[i-1][j-1] == 2 ? 1:0;
                }
                if(board[i][j] == 0 && lives == 3){// 更新
                    board[i][j] = 3;//dead->live
                } else if(board[i][j] == 1){
                    if(lives < 2 || lives > 3){
                        board[i][j] = 2;//live->dead
                    }
                }
            }
        }
        for(int i = 0; i < m; ++i){// 解码
            for(int j = 0; j < n; ++j){
                board[i][j] = board[i][j] % 2;
            }
        }
    }

    public static void main(String[] args) {
        gameOfLife go = new gameOfLife();
        int[][] board = {{0,0,0,0},
                    {0,1,1,0},
                {0,1,1,0},
                {0,0,0,0}};
        int m = board.length;
        int n = board[0].length;
        go.gameOfLife(board);
        for(int i = 0;i<m;i++){//i:行
            for(int j = 0;j<n;j++){
                System.out.print(board[i][j]);System.out.print(" ");
            }
            System.out.println();}
    }
}
